/*
     Copyright 2007 Joseph M. Ferner

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.Net.Sockets;
using System.Threading;
using OpenServers.Net.Common.Listener;
using OpenServers.Net.Common.Socket;

namespace OpenServers.Net.Common.State {
    /// <summary>
    /// delegate for handling data received events.
    /// </summary>
    public delegate void DataReceivedDelegate(IState state, byte[] buffer, int received);
    
    /// <summary>
    /// delegate for handling connection closed events.
    /// </summary>
    public delegate void ConnectionClosedDelegate(IState state);

    /// <summary>
    /// delegate for handling connection opened events.
    /// </summary>
    public delegate void ConnectionOpenedDelegate(IState state);

    /// <summary>
    /// delegate for handling thread attach events.
    /// </summary>
    public delegate void AttachThreadDelegate(IState state, Thread thread);

    /// <summary>
    /// delegate for handling thread detach events.
    /// </summary>
    public delegate void DetachThreadDelgate(IState state, Thread thread);

    /// <summary>
    /// delegate for handling error events.
    /// </summary>
    public delegate void ErrorDelegate(IState state, Exception ex);

    /// <summary>
    /// State object passed around the server as a connection is processed.
    /// </summary>
    public interface IState {
        /// <summary>
        /// Buffer for use by the receive functions to hold async data.
        /// </summary>
        byte[] ReceiveBuffer { get; }

        /// <summary>
        /// The client socket.
        /// </summary>
        ISocket ClientSocket { get; }

        /// <summary>
        /// flag indicating that the server should close the socket.
        /// </summary>
        bool CloseConnection { get; set; }

        /// <summary>
        /// The listener that received this client.
        /// </summary>
        IListener Listener { get; }

        /// <summary>
        /// called when data is received on the socket.
        /// </summary>
        event DataReceivedDelegate DataReceived;

        /// <summary>
        /// called when the connection is opened.
        /// </summary>
        event ConnectionOpenedDelegate ConnectionOpened;

        /// <summary>
        /// called when the connection is closed.
        /// </summary>
        event ConnectionClosedDelegate ConnectionClosed;

        /// <summary>
        /// called when the state is passed to another thread.
        /// </summary>
        event AttachThreadDelegate AttachThread;

        /// <summary>
        /// called when the state is about to be removed from a thread.
        /// </summary>
        event DetachThreadDelgate DetachThread;

        /// <summary>
        /// Called when an exception or error has occured.
        /// </summary>
        event ErrorDelegate Error;

        /// <summary>
        /// fires the ConnectionOpened event.
        /// </summary>
        void FireConnectionOpened();

        /// <summary>
        /// fires the ConnectionClosed event.
        /// </summary>
        void FireConnectionClosed();

        /// <summary>
        /// fires the AttachThread event.
        /// </summary>
        void FireAttachThread(Thread thread);

        /// <summary>
        /// fires the DetachThread event.
        /// </summary>
        void FireDetachThread(Thread thread);

        /// <summary>
        /// fires the DataReceived event.
        /// </summary>
        void FireDataReceived(int numberOfBytesReceived);

        /// <summary>
        /// Fires the Error event.
        /// </summary>
        void FireError(Exception ex);
    }
}
